package org.example.zookeeper.inspect;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryForever;
import org.apache.zookeeper.data.Stat;
import org.example.zookeeper.config.ZkProperties;

import java.util.ArrayList;
import java.util.List;

public class DubboInspect {
    public List<ServiceInfo> inspect(ZkProperties zkConfig) throws Exception {
        RetryPolicy retryPolicy = new RetryForever(1000);//new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory
                .newClient(zkConfig.getServer(), zkConfig.getSessionTimeout(), zkConfig.getConnectionTimeout(), retryPolicy);
        client.start();
        try {
            //consumers, configurators, routers, providers
            List<ServiceInfo> serviceInfos = new ArrayList<>();
            List<String> services = getServices(client);
            for (String service : services) {
                serviceInfos.add(inspectService(client, service));
            }
            return serviceInfos;
        } finally {
            if (client != null) {
                client.close();
            }
        }
    }

    private List<String> getServices(CuratorFramework client) throws Exception {
        List<String> services = client.getChildren().forPath("/dubbo");
        return services;
    }

    private ServiceInfo inspectService(CuratorFramework client, String service) throws Exception {
        String path = "/dubbo/" + service + "/";
        ServiceInfo serviceInfo = new ServiceInfo(service);
        serviceInfo.setProviders(getNumChildren(client, path + "providers"));
        serviceInfo.setConfigurators(getNumChildren(client, path + "configurators"));
        serviceInfo.setRouters(getNumChildren(client, path + "routers"));
        serviceInfo.setConsumers(getNumChildren(client, path + "consumers"));
        return serviceInfo;
    }

    private int getNumChildren(CuratorFramework client, String path) throws Exception {
        Stat stat = client.checkExists().forPath(path);
        return stat.getNumChildren();
    }
}
